/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package vodjaho.jms.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.swing.JOptionPane;
import vodjaho.jms.ui.ConsumerFrame;
import vodjaho.jms.ui.ProducerFrame;
import vodjaho.jms.util.MyUtil;

/**
 *
 * @author Maxim A. Kanev <ask.me.makes@gmail.com> [mkanev]
 */
public class MessagesMediator {

    private ConnectionFactory factory;
    private Topic topic;
    private ProducerFrame producerFrame;
    private ConsumerFrame consumerFrame;
    private Connection topicConnection;
    private Session session;
    private TextMessage message;
    private MessageProducer producer;
    private MessageConsumer consumer;
    private boolean connected;

    public MessagesMediator(ConnectionFactory factory, Topic topic) {
        this.factory = factory;
        this.topic = topic;

        producerFrame = new ProducerFrame();
        consumerFrame = new ConsumerFrame();
        try {
            initJMSComponents();
            consumer.setMessageListener(consumerFrame);
        } catch (JMSException ex) {
            JOptionPane.showConfirmDialog(producerFrame, "There was a problem with JMS connection.");
            MyUtil.prettyStackPrint(ex);
            System.exit(0);
        }
        producerFrame.getStartButton().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                getProducerFrame().startGenerator(new Runnable() {

                    @Override
                    public void run() {
                        Random random = new Random();
                        try {
                            while (true) {
                                String status = random.nextBoolean() ? "online" : "offline";
                                sendTextMessage(status);
                                Thread.sleep(random.nextInt(1000) + 100);
                            }
                        } catch (InterruptedException ex) {
                            MyUtil.prettyStackPrint(ex);
                            Thread.currentThread().interrupt();
                        }
                    }
                });
            }
        });
        producerFrame.getStopButton().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                getProducerFrame().stopGenerator();
                try {
                    doDisconnect();
                } catch (JMSException ex) {
                    MyUtil.prettyStackPrint(ex);
                }
            }
        });
        producerFrame.getSendButton().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                String message = getProducerFrame().getMessageField().getText();
                sendTextMessage(message);
            }
        });
    }

    public ConsumerFrame getConsumerFrame() {
        return consumerFrame;
    }

    public ProducerFrame getProducerFrame() {
        return producerFrame;
    }

    private void initJMSComponents() throws JMSException {
        topicConnection = factory.createConnection();
        doConnect();
        session = topicConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        message = session.createTextMessage();
        producer = session.createProducer(topic);
        consumer = session.createConsumer(topic);
    }

    private void sendTextMessage(String msg) {
        try {
            if (!connected) {
                doConnect();
            }
            message.setText(msg);
            producer.send(message);
        } catch (JMSException ex) {
            MyUtil.prettyStackPrint(ex);
        }
    }

    private void doConnect() throws JMSException {
        topicConnection.start();
        connected = true;
    }

    private void doDisconnect() throws JMSException {
        topicConnection.stop();
        connected = false;
    }
}
